# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView     # pip install PyQtWebEngine
from Ui_main_ui import Ui_MainWindow
from PyQt5 import QtCore
import qdarkstyle
import JsCode as Js
import jqdatasdk as jq   #聚宽数据包
import pandas as pd
from datetime import datetime
from threading import Timer

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())  # 设置窗体主题颜色
        self.view = None
        self.js_init = False    
        self.WebView()
        self.JQlogin('手机号码','密码')
        self.KlineData = self.JqHistory(ExchangeID=b'SHFE',      # 交易所代码
                                        InstrumentID=b'rb2005',  # 合约代码
                                        End_date=datetime.now().strftime('%Y-%m-%d %H:%M:%S'),  # 今天的时间
                                        frequency=str(1440),        # 1440 分钟为1天的时间，就是获取日线
                                        count=300) # 获取指定时间前count根K线数据

        self.upKline()

    def WebView(self):
        self.view = QWebEngineView()    # 创建浏览器对象
        self.gridLayout.addWidget(self.view)     # 显示窗体
        self.load_html()

    def load_html(self):
        self.view.setHtml(Js.html, QtCore.QUrl("index.html"))
        self.view.loadFinished.connect(self.set_options)

    def set_options(self):
        ''' 设置 myChart.setOption 初始化以及各项配置 '''
        if not self.view:    # 如果浏览器对象没有创建
            self.js_init = False    # 将js初始化设置为假
            return  # 并直接返回退出
        
        if not self.js_init:
            # 初始化echarts
            self.view.page().runJavaScript(Js.Pos_Js)       # 执行js页面交互，页面CSS布局和美化
            self.view.page().runJavaScript(Js.splitData)    # 载入K线处理函数
            self.view.page().runJavaScript(Js.echart_init)  # echart 初始化
            self.view.page().runJavaScript(Js.Formula_js)   # 指标
            self.view.page().runJavaScript(
                f'''
                    var KNAME, data, macd;
                    var Zstart = 80;
                    var Zend = 100;
                    var MA1=0, MA2=0, MA3=0, MA4=0, MA5=0, MA6=0;
                    var color1 = "#0CF49B";
                    var color2 = "#FD1050";
                    myChart.clear();
                    var option = eval({Js.Kline_js});
                    myChart.setOption(option);
                '''
            )
            self.view.page().runJavaScript(Js.websize)  # 页面自适应窗体
            self.js_init = True

    def DftoList(self, df):
        ''' 格式转换 '''
        a=[x.strftime("%Y-%m-%d %H:%M:%S") for x in df.index]
        df.insert(0,'date', a)
        df=df.reset_index(level=None, drop=True ,col_level=0, col_fill='')
        return df

    def JQlogin(self, user, password):
        ''' 手机号, 密码 '''
        try:
            jq.auth(user, password)   
            count=jq.get_query_count()
            print('当日可请求条数：', count['total'], '剩余：',count['spare'])
        except Exception as e:
            print('JQLogin_ERROR:',e)

    def JqHistory(self, ExchangeID = '', InstrumentID = '', Start_date=None, End_date=None, frequency=None, count = None):
        'JQ获取历史'
        ExchangeID = str(ExchangeID, encoding = "utf8")
        try:
            if ExchangeID == 'SHFE':
                InstrumentID=str(InstrumentID, encoding = "utf8").upper() +'.XSGE'   # 上海期货交易所
            elif ExchangeID == 'DCE':
                InstrumentID=str(InstrumentID, encoding = "utf8").upper() +'.XDCE'   # 大连商品交易所
            elif ExchangeID == 'CFFEX':
                InstrumentID=str(InstrumentID, encoding = "utf8").upper() +'.CCFX'   # 中国金融期货交易所
            elif ExchangeID == 'CZCE':
                InstrumentID=str(InstrumentID, encoding = "utf8").upper() +'.XZCE'   # 郑州商品交易所
            elif ExchangeID == 'INE':
                InstrumentID=str(InstrumentID, encoding = "utf8").upper() +'.XSGE'
            jdf = jq.get_price(InstrumentID, start_date=Start_date, 
                                end_date=End_date, frequency=str(frequency)+'m', count=count,
                                fields=['open', 'close', 'low', 'high', 'volume'])
            # print(jdf)
            return jdf
        except Exception as e:
            print('历史数据获取失败，使用实盘数据初始化', e)


    def upKline(self, data=None):
        ''' 刷新K线 '''
        if not self.view:    # 如果浏览器对象没有创建
            return  # 并直接返回退出

        if data is None:
            data = self.KlineData   # KlineData 用于暂存K线数据，K线数据可在多线程中实时更新赋值
        
        if isinstance(data, pd.core.frame.DataFrame):   # K线数据为DataFrame类型数据
            kdata = data.copy() # 为了不污染原始数据而复制一份
            kdata = self.DftoList(kdata).values.tolist()    # 由于Echarts中需使用List类型数据这里做一次转换
            self.view.page().runJavaScript(
                f'''
                    KNAME= "K线";
                    data = splitData({kdata});
                    macd = MACD(12, 26, 9, data.datas, 1);
                    MA1 = MA(20, data.datas, 1);
                    MA2 = MA(60, data.datas, 1);
                    MA3 = MA(120, data.datas, 1);
                    option = eval({Js.Kline_js});
                '''
            )
            self.view.page().runJavaScript(
                '''
                    myChart.on('dataZoom',function(event){
                        if(event.batch){
                                Zstart=event.batch[0].start;
                                Zend=event.batch[0].end;
                        }else{
                                Zstart=event.start;
                                Zend=event.end;
                        };
                    });

                    myChart.setOption(option);

                '''
            )
        sTimer = Timer(1.0, self.upKline, (None,)).start()  # 启动定时器定时刷新数据

        
if __name__ == "__main__":
    app = QApplication(sys.argv)
    Main = MainWindow()
    Main.show()
    sys.exit(app.exec_())